﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Drawing.Printing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace KC.Presentation.Mv8CMS
{
	public partial class ResistPostEditor : Form
	{
		private string csMv8 = System.Configuration.ConfigurationManager.ConnectionStrings["MV8"].ConnectionString;
		private int PostID = -1;

		public ResistPostEditor() { InitializeComponent(); }
		public ResistPostEditor(int postID) { 
			InitializeComponent();
			PostID = postID;
			DataRow dr = KC.DataAccess.Global.Global.CallSql_Query(csMv8, "select * from resist..Posts where ID=" + PostID.ToString()).Rows[0];
			txtTitle.Text = dr["Title"].ToString();
			txtBody.Text = dr["Body"].ToString();
			cbEnabled.Checked = (bool)dr["isEnabled"];
			lblFriendlyName.Text = dr["Friendlyname"].ToString();

			if (dr["Image"].GetType()!=typeof(DBNull)) try {
				byte[] obj = (byte[])dr["Image"];
				if (obj.Length > 50)
					pbImg.Image = Image.FromStream(new MemoryStream((byte[])obj)); } catch { } 
		}
		private void ResistPostEditor_Load(object sender, EventArgs e) {
			// Select post categories
			LoadCats();
			DataRow[] dtCats = KC.DataAccess.Global.Global.CallSql_Query(csMv8, "select CategoryID from resist..PostCategoryMap where PostID=" + PostID.ToString()).Select();
			lbCategories.SelectedItems.Clear();
			for (int i = 0; i < lbCategories.Items.Count; i++)
				if (dtCats.Where(c => c["CategoryID"].ToString() == ((DataRowView)lbCategories.Items[i])["ID"].ToString()).Count() > 0)
					lbCategories.SelectedItems.Add(lbCategories.Items[i]);
		}
		private void btnFriendlyName_Click(object sender, EventArgs e)
		{
			BuildFriendlyName();
		}
		private void btnSaveContinue_Click(object sender, EventArgs e) { Save(); }
		private void btnOK_Click(object sender, EventArgs e)
		{
			Save();
			DialogResult = System.Windows.Forms.DialogResult.OK;
			Close();
		}
		private void btnDelete_Click(object sender, EventArgs e)
		{
			if (PostID > -1) KC.DataAccess.Global.Global.CallSql_Query(csMv8, "delete resist..PostCategoryMap where PostID=" + PostID.ToString() + "; delete resist..Posts where ID=" + PostID.ToString());
			DialogResult = System.Windows.Forms.DialogResult.OK;
			Close();
		}
		private void pbImg_Click(object sender, EventArgs e)
		{
			if (pbImg.Image != null) {
				KC.DataAccess.Global.Global.CallSql_Query(csMv8, "update resist..posts set image = null where id=" + PostID.ToString());
				pbImg.Image = null;
				return; }

			// Get filename and create thumbnail
			OpenFileDialog ofd = new OpenFileDialog() { CheckFileExists = true, CheckPathExists = true, Multiselect = false, FileName = "*.png; *.bmp; *.jp*g; *.gif" };
			if (ofd.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
			string filename = ofd.FileName;
			string filename2 = Path.GetTempFileName();
			if (!CreateThumbnail(filename, filename2, 200))
				filename2 = filename;

			// Read the image into a byte array
			byte[] data = null;
			FileInfo fInfo = new FileInfo(filename2);
			long numBytes = fInfo.Length;
			FileStream fs = new FileStream(filename2, FileMode.Open, FileAccess.Read);
			BinaryReader br = new BinaryReader(fs);
			data = br.ReadBytes((int)numBytes);

			// Save avatar to SQL 
			using (SqlCommand comm = new SqlCommand("update resist..posts set image=@imagedata where id=" + PostID.ToString(), new SqlConnection(csMv8))) {
				comm.Parameters.AddWithValue("imagedata", (object)data);
				comm.Connection.Open();
				comm.ExecuteNonQuery();
				comm.Connection.Close(); }
			
			// Update picturebox
			pbImg.Image = Image.FromFile(filename2);
			for (int i = 0; i < 10; i++)
				try { File.Delete(filename2); break; }
				catch { System.Threading.Thread.Sleep(100); }
		}
		private void lblFriendlyName_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			System.Diagnostics.Process.Start("http://www.ResistOccupation.com/Post.aspx?" + lblFriendlyName.Text);
		}
		private void txtBody_TextChanged(object sender, EventArgs e) 
		{ 
			lblSize.Text = txtBody.Text.Length.ToString();
			if (txtBody.Text.Contains("!break")) lblSize.Text = txtBody.Text.IndexOf("!break") + " / " + lblSize.Text;
		}

		private void BuildFriendlyName()
		{
			string FriendlyName = System.Web.HttpUtility.UrlEncode(txtTitle.Text);
			int iteration = 0;
			while (KC.DataAccess.Global.Global.CallSql_Query(csMv8, "select count(ID) from resist..Posts where FriendlyName='" + FriendlyName.Replace("'", "''") + "' and ID <> " + PostID.ToString()).Rows[0][0].ToString() != "0")
			{
				iteration++;
				FriendlyName = System.Web.HttpUtility.UrlEncode(txtTitle.Text) + iteration.ToString();
			}
			lblFriendlyName.Text = FriendlyName;
		}
		private void LoadCats()
		{
			lbCategories.DataSource = KC.DataAccess.Global.Global.CallSql_Query(csMv8, "select ID, Name from resist..Categories order by Name");
			lbCategories.DisplayMember = "Name";
			lbCategories.ValueMember = "ID";
		}
		private void Save()
		{
			if (lblFriendlyName.Text == "(None") BuildFriendlyName();
			string query = "";
			if (PostID == -1) query = "insert into resist..Posts (Title, Description, Body, Created, FriendlyName, Keywords, isEnabled) values (" +
				"'" + txtTitle.Text.Replace("'", "''") + "', '', '" + txtBody.Text.Replace("'", "''") + "', getdate(), '" + lblFriendlyName.Text.Replace("'", "''") + "', '', " + (cbEnabled.Checked ? "1" : "0") + "); select @@IDENTITY; ";
			else query = "update resist..Posts set Title='" + txtTitle.Text.Replace("'", "''") + "', Description='', Body='" + txtBody.Text.Replace("'", "''") + "', FriendlyName='" + lblFriendlyName.Text.Replace("'", "''") + "'" +
				", keywords='', isEnabled=" + (cbEnabled.Checked ? "1" : "0") + " where ID=" + PostID.ToString() + ";";

			query += "delete resist..PostCategoryMap where PostID=" + PostID.ToString() + "; ";
			foreach (object obj in lbCategories.SelectedItems)
				query += "insert into resist..PostCategoryMap (PostID, CategoryID) values (" + (PostID == -1 ? "@@IDENTITY" : PostID.ToString()) + ", " + ((DataRowView)obj)["ID"].ToString() + "); ";
			DataTable dt = KC.DataAccess.Global.Global.CallSql_Query(csMv8, query);
			if (PostID == -1 && dt.Rows.Count > 0) PostID = int.Parse(dt.Rows[0][0].ToString());
		}
		public static bool CreateThumbnail(string inFile, string outFile, int x)
		{
			// Validation - assume 16x16 icon is smallest useful size. Smaller than that is just not going to do us any good 
			// anyway. I consider that an "Exceptional" case. 
			if (string.IsNullOrEmpty(inFile)) throw new ArgumentNullException("inFile");
			if (string.IsNullOrEmpty(outFile)) throw new ArgumentNullException("outFile");
			if (x < 16) throw new ArgumentOutOfRangeException("x");
			if (!File.Exists(inFile)) throw new FileNotFoundException("inFile", "File does not exist: " + inFile);

			// Mathematically determine Y dimension
			int y;
			using (Image img = Image.FromFile(inFile))
				y = (int)((double)img.Height * ((double)x / (double)img.Width));

			using (Bitmap bmp = new Bitmap(inFile))
			using (Bitmap thumb = new Bitmap((Image)bmp, new Size(x, y)))
			using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(thumb))
			{
				g.SmoothingMode = SmoothingMode.HighQuality;
				g.InterpolationMode = InterpolationMode.High;
				g.CompositingQuality = CompositingQuality.HighQuality;
				ImageCodecInfo codec = ImageCodecInfo.GetImageEncoders()[1];
				EncoderParameters ep2 = new EncoderParameters(1);
				ep2.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
				g.DrawImage(bmp, new Rectangle(0, 0, thumb.Width, thumb.Height));
				try { thumb.Save(outFile, codec, ep2); return true; }
				catch { return false; }
			}
		}

	}
}
